package com.ntschy.framework.aspectj;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.ntschy.common.annotation.ListDataScope;
import com.ntschy.common.core.BaseEntity;
import com.ntschy.common.core.entity.dataobject.SysMenu;
import com.ntschy.common.core.entity.dataobject.SysUser;
import com.ntschy.common.core.entity.enums.SysDataScopeEnum;
import com.ntschy.common.core.model.LoginUser;
import com.ntschy.common.utils.ServletUtils;
import com.ntschy.common.utils.spring.SpringUtils;
import com.ntschy.framework.service.TokenService;
import com.ntschy.sys.service.ISysRoleService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.util.List;

/**
 * 列表数据过滤处理
 *
 * @author ezreal_geng
 */
@Aspect
@Component
public class ListDataScopeAspect {

    @Autowired
    private ISysRoleService roleService;


    // 配置织入点
    @Pointcut("@annotation(com.ntschy.common.annotation.ListDataScope)")
    public void dataScopePointCut() {
    }

    @Before("dataScopePointCut()")
    public void doBefore(JoinPoint point) throws Throwable {
        handleDataScope(point);
    }

    protected void handleDataScope(final JoinPoint joinPoint) {
        // 获得注解
        ListDataScope controllerDataScope = getAnnotationLog(joinPoint);
        if(ObjectUtil.isNull(controllerDataScope)) {
            return;
        }
        // 获取当前的用户
        LoginUser loginUser = SpringUtils.getBean(TokenService.class).getLoginUser(ServletUtils.getRequest());
        if (ObjectUtil.isNotNull(loginUser)) {
            SysUser currentUser = loginUser.getUser();
            // 如果是超级管理员，则不过滤数据
            if (ObjectUtil.isNotNull(currentUser) && !currentUser.isAdmin()) {
                dataScopeFilter(joinPoint, currentUser, controllerDataScope.mainAlias(), controllerDataScope.mainField(), controllerDataScope.uri());
            }
        }
    }

    /**
     * 数据范围过滤
     */
    public void dataScopeFilter(JoinPoint joinPoint, SysUser user, String mainAlias, String mainField, String uri) {

        SysMenu currentMenu = null;
        List<SysMenu> menuBtnList = roleService.listMenuByRole(user.getRole().getRoleKey());
        for (int i = 0; i < menuBtnList.size(); i++) {
            SysMenu menu = menuBtnList.get(i);
            if(uri.equals(menu.getHttpUrl())) {
                currentMenu = menu;
                break;
            }
        }

        if(ObjectUtil.isNotNull(currentMenu)) {
            StringBuilder sqlString = new StringBuilder();

            if (SysDataScopeEnum.ALL == currentMenu.getDataScope()) {
                sqlString.append(" AND ( 1 = 1 )");
            } else if (SysDataScopeEnum.COMPANY == currentMenu.getDataScope()) {
                sqlString.append(StrUtil.format("  AND ( {}.{} IN ( SELECT ID FROM SYS_USER_DEPT WHERE CompanyID = {} ) ) ", mainAlias, mainField, user.getId(), user.getCompanyId()));
            } else if (SysDataScopeEnum.DEPT == currentMenu.getDataScope()) {
                sqlString.append(StrUtil.format(" AND ( {}.{} IN ( SELECT ID FROM SYS_USER_DEPT WHERE DeptID = {} ) ) ", mainAlias, mainField, user.getId(), user.getDept()));
            } else if (SysDataScopeEnum.SELF == currentMenu.getDataScope()) {
                sqlString.append(StrUtil.format(" AND ( {}.{} = '{}' ) ", mainAlias, mainField, user.getId()));
            }

            if (StrUtil.isNotBlank(sqlString.toString())) {
                Object params = joinPoint.getArgs()[0];
                if (ObjectUtil.isNotNull(params) && params instanceof BaseEntity) {
                    BaseEntity baseEntity = (BaseEntity) params;
                    baseEntity.setCurrentDataScope(sqlString.toString());
                    //baseEntity.getParams().put(DATA_SCOPE, " AND (" + sqlString.substring(4) + ")");
                }
            }
        }




        // SELECT CompanyID FROM sys_user WHERE userID = {}
//        else if (DATA_SCOPE_CUSTOM == dataScope) {
//            sqlString.append(StrUtil.format(
//                    " OR {}.dept_id IN ( SELECT dept_id FROM sys_role_dept WHERE role_id = {} ) ", deptAlias,
//                    role.getId()));
//        } else if (DATA_SCOPE_DEPT == dataScope) {
//            sqlString.append(StrUtil.format(" OR {}.dept_id = {} ", deptAlias, user.getDeptId()));
//        } else if (DATA_SCOPE_DEPT_AND_CHILD == dataScope) {
//            sqlString.append(StrUtil.format(
//                    " OR {}.dept_id IN ( SELECT dept_id FROM sys_dept WHERE dept_id = {} or find_in_set( {} , ancestors ) )",
//                    deptAlias, user.getDeptId(), user.getDeptId()));
//        } else if (DATA_SCOPE_SELF == dataScope) {
//            if (StrUtil.isNotBlank(userAlias)) {
//                sqlString.append(StrUtil.format(" OR {}.user_id = {} ", userAlias, user.getId()));
//            } else {
//                // 数据权限为仅本人且没有userAlias别名不查询任何数据
//                sqlString.append(" OR 1=0 ");
//            }
//        }
    }

    /**
     * 是否存在注解，如果存在就获取
     */
    private ListDataScope getAnnotationLog(JoinPoint joinPoint) {
        Signature signature = joinPoint.getSignature();
        MethodSignature methodSignature = (MethodSignature) signature;
        Method method = methodSignature.getMethod();

        if (method != null) {
            return method.getAnnotation(ListDataScope.class);
        }
        return null;
    }
}
